package cn.xingzhe.monster.user.interfaces.controller;

import cn.xingzhe.monster.user.application.dto.UserDTO;
import cn.xingzhe.monster.user.application.service.CaptchaApplicationService;
import cn.xingzhe.monster.user.application.service.UserApplicationService;
import cn.xingzhe.monster.user.interfaces.converter.UserConverter;
import cn.xingzhe.monster.user.interfaces.request.*;
import cn.xingzhe.monster.user.interfaces.vo.LoginResponse;
import cn.xingzhe.monster.user.interfaces.vo.UserVO;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import open.intellijboy.framework.core.response.Result;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

/**
 * 用户控制器
 *
 * @author System
 * @version 1.0.0
 * @since 2024-01-01
 */
@Tag(name = "用户模块", description = "用户注册、登录、信息查询等业务场景功能接口")
@RestController
@RequestMapping("/users")
public class UserController {

    private final UserApplicationService userApplicationService;
    private final CaptchaApplicationService captchaApplicationService;
    private final UserConverter userConverter;

    public UserController(UserApplicationService userApplicationService,
                          CaptchaApplicationService captchaApplicationService,
                          UserConverter userConverter) {
        this.userApplicationService = userApplicationService;
        this.captchaApplicationService = captchaApplicationService;
        this.userConverter = userConverter;
    }

    /**
     * 邮箱注册
     */
    @Operation(summary = "邮箱注册", description = "通过邮箱和验证码注册新用户，注册成功后自动登录")
    @PostMapping("/register/email")
    public Result<UserVO> registerByEmail(
            @Parameter(description = "邮箱注册请求", required = true)
            @Validated @RequestBody EmailRegisterRequest request) {
        UserDTO userDTO = userApplicationService.registerByEmail(
                request.getEmail(),
                request.getPassword(),
                request.getCaptcha()
        );
        return Result.success(userConverter.toVO(userDTO));
    }

    /**
     * 手机号注册
     */
    @Operation(summary = "手机号注册", description = "通过手机号和验证码注册新用户，注册成功后自动登录")
    @PostMapping("/register/phone")
    public Result<UserVO> registerByPhone(
            @Parameter(description = "手机号注册请求", required = true)
            @Validated @RequestBody PhoneRegisterRequest request) {
        UserDTO userDTO = userApplicationService.registerByPhone(
                request.getPhone(),
                request.getPassword(),
                request.getCaptcha()
        );
        return Result.success(userConverter.toVO(userDTO));
    }

    /**
     * 用户名密码登录
     */
    @Operation(summary = "用户名密码登录", description = "使用用户名和密码进行登录认证")
    @PostMapping("/login/username")
    public Result<LoginResponse> loginByUsername(
            @Parameter(description = "用户名登录请求", required = true)
            @Validated @RequestBody UsernameLoginRequest request) {
        UserDTO userDTO = userApplicationService.loginByUsername(
                request.getUsername(),
                request.getPassword()
        );
        String token = userApplicationService.getCurrentToken();
        LoginResponse response = LoginResponse.builder()
                .token(token)
                .user(userConverter.toVO(userDTO))
                .build();
        return Result.success(response);
    }

    /**
     * 邮箱登录
     */
    @Operation(summary = "邮箱登录", description = "使用邮箱和验证码进行登录认证")
    @PostMapping("/login/email")
    public Result<LoginResponse> loginByEmail(
            @Parameter(description = "邮箱登录请求", required = true)
            @Validated @RequestBody EmailLoginRequest request) {
        UserDTO userDTO = userApplicationService.loginByEmail(
                request.getEmail(),
                request.getCaptcha()
        );
        String token = userApplicationService.getCurrentToken();
        LoginResponse response = LoginResponse.builder()
                .token(token)
                .user(userConverter.toVO(userDTO))
                .build();
        return Result.success(response);
    }

    /**
     * 手机号登录
     */
    @Operation(summary = "手机号登录", description = "使用手机号和验证码进行登录认证")
    @PostMapping("/login/phone")
    public Result<LoginResponse> loginByPhone(
            @Parameter(description = "手机号登录请求", required = true)
            @Validated @RequestBody PhoneLoginRequest request) {
        UserDTO userDTO = userApplicationService.loginByPhone(
                request.getPhone(),
                request.getCaptcha()
        );
        String token = userApplicationService.getCurrentToken();
        LoginResponse response = LoginResponse.builder()
                .token(token)
                .user(userConverter.toVO(userDTO))
                .build();
        return Result.success(response);
    }

    /**
     * 发送验证码
     */
    @Operation(summary = "发送验证码", description = "向指定邮箱或手机号发送验证码，支持注册和登录两种类型")
    @PostMapping("/captcha/send")
    public Result<String> sendCaptcha(
            @Parameter(description = "发送验证码请求", required = true)
            @Validated @RequestBody SendCaptchaRequest request) {
        try {
            captchaApplicationService.sendCaptcha(request.getKey(), request.getType());
            return Result.success("验证码发送成功");
        } catch (IllegalArgumentException e) {
            return Result.failure(e.getMessage());
        }
    }

    /**
     * 获取当前用户信息
     */
    @Operation(summary = "获取当前用户信息", description = "获取当前登录用户的详细信息，包括用户基本信息、角色和权限")
    @GetMapping("/info")
    public Result<UserVO> getCurrentUserInfo() {
        String userId = userApplicationService.getCurrentUserId();
        if (userId == null) {
            return Result.failure("用户未登录");
        }
        UserDTO userDTO = userApplicationService.getUserById(userId);
        return Result.success(userConverter.toVO(userDTO));
    }

    /**
     * 退出登录
     */
    @Operation(summary = "退出登录", description = "当前用户退出登录，销毁会话Token")
    @PostMapping("/logout")
    public Result<String> logout() {
        userApplicationService.logout();
        return Result.success("退出登录成功");
    }

}

